package com.blog.controller;

import com.blog.entity.Blog;
import com.blog.entity.Comment;
import com.blog.lucene.BlogIndex;
import com.blog.service.BlogService;
import com.blog.service.CommentService;
import com.blog.util.StringUtil;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 师晓峰
 * @version V1.0
 * @date 2023/9/15 0:47
 * @Description: 博客详情
 */
@Controller
@RequestMapping({"/blog"})
public class BlogController {

    @Resource
    private BlogService blogService;

    @Resource
    private CommentService commentService;

    private BlogIndex blogIndex = new BlogIndex();

    @RequestMapping({"/articles/{id}"})
    public ModelAndView details(@PathVariable("id") Integer id, HttpServletRequest request) {
        ModelAndView mav = new ModelAndView();
        // 根据主键查询博客信息
        Blog blog = blogService.findById(id);
        // 阅读数量 + 1
        blog.setClickHit(blog.getClickHit() + 1);
        blogService.update(blog);

        mav.addObject("mainPage", "foreground/blog/view.jsp");
        mav.addObject("pageTitle", blog.getTitle() + "_个人博客系统");
        mav.addObject("blog", blog);
        // 上一篇和下一篇
        mav.addObject("pageCode", genUPAndDownPageCode(blogService.getLastBlog(id), blogService.getNextBlog(id), request.getServletContext().getContextPath()));

        // 查询评论信息
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("blogId", blog.getId());
        map.put("state", 1);
        List<Comment> commentList = commentService.list(map);
        mav.addObject("commentList", commentList);

        // 处理关键词
        String keyWord = blog.getKeyWord();
        if (StringUtil.isEmpty(keyWord)) {
            mav.addObject("keyWords", null);
        }else{
            String[] keyWords = keyWord.split(" ");
            // 处理多个空格问题
            mav.addObject("keyWords", StringUtil.filterWhite(Arrays.asList(keyWords)));
        }
        mav.setViewName("index");
        return mav;
    }

    /**
     * 上一篇和下一篇
     *
     * @param lastBlog
     * @param nextBlog
     * @param projectContext
     * @return
     */
    public String genUPAndDownPageCode(Blog lastBlog, Blog nextBlog, String projectContext) {
        StringBuffer pageCode = new StringBuffer();
        if (lastBlog == null || lastBlog.getId() == null) {
            pageCode.append("<p>上一篇：没有了</P>");
        } else {
            pageCode.append("<p>上一篇: <a href='" + projectContext + "/blog/articles/" + lastBlog.getId() + ".html'>" + lastBlog.getTitle() + "</a></P>");
        }

        if (nextBlog == null || nextBlog.getId() == null) {
            pageCode.append("<p>下一篇：没有了</P>");
        } else {
            pageCode.append("<p>下一篇: <a href='" + projectContext + "/blog/articles/" + nextBlog.getId() + ".html'>" + nextBlog.getTitle() + "</a></P>");
        }

        return pageCode.toString();
    }

    /**
     * 根据关键词查询
     * @param q
     * @param page
     * @param request
     * @return
     * @throws ParseException
     * @throws InvalidTokenOffsetsException
     * @throws IOException
     */
    @RequestMapping({"/q"})
    public ModelAndView q(@RequestParam(value = "q", required = false) String q,
                          @RequestParam(value = "page", required = false) String page,
                          HttpServletRequest request) throws ParseException, InvalidTokenOffsetsException, IOException {
        if (StringUtil.isEmpty(page)){
            page = "1";
        }
        ModelAndView mav = new ModelAndView();
        mav.addObject("mainPage","foreground/blog/result.jsp");
        // 在lucene 中查询
        List<Blog> blogList = blogIndex.selectBlog(q.trim());

        mav.addObject("q",q);
        mav.addObject("resultTotal",blogList.size());
        int toIndex = 0;
        if (blogList.size() >= Integer.parseInt(page) * 10){
            toIndex = Integer.parseInt(page) * 10;
        }else{
            toIndex = blogList.size();
        }
        // 1 页   0  10
        mav.addObject("blogList",blogList.subList((Integer.parseInt(page)-1) * 10,toIndex));


        mav.addObject("pageCode",genUpAndDownPageCode(Integer.parseInt(page),blogList.size(),q,10,request.getServletContext().getContextPath()));
        mav.addObject("pageTitle","搜索关键词'" + q+ "'结果页面");

        mav.setViewName("index");
        return mav;
    }



    /**
     * 查询结果翻页
     *
     * @param page
     * @param totalNum
     * @param q
     * @param pageSize
     * @param projectContext
     * @return
     */
    private String genUpAndDownPageCode(int page, int totalNum, String q, int pageSize, String projectContext) {
        StringBuffer pageCode = new StringBuffer();
        // 总页数计算
        int totalPage = totalNum % pageSize == 0 ? totalNum / pageSize : totalNum / pageSize + 1;
        if (totalPage == 0) {
            return "";
        }
        //
        pageCode.append("<nav>");
        pageCode.append("<ur class='pager'>");
        // 如果当前页数大于1
        if (page > 1) {
            pageCode.append("<li><a href='" + projectContext + "/blog/q.html?page=" + (page - 1) + "&q=" + "'>上一页</a></li>");
        }else{
            // 当前页为第一页
            pageCode.append("<li class='disabled'><a href='#'>上一页</a></li>");
        }
        // 不是最后一页
        if (page < totalPage){
            pageCode.append("<li><a href='" + projectContext + "/blog/q.html?page=" + (page + 1) + "&q=" + "'>下一页</a></li>");
        }else{
            // 当前页为最后1页
            pageCode.append("<li class='disabled'><a href='#'>下一页</a></li>");
        }

        pageCode.append("</ur>");
        pageCode.append("</nav>");
        return pageCode.toString();
    }
}
